<!--Tinymce富文本编辑器组件，比Quill功能更全面，该组件在弹窗中注意使用v-if控制关闭打开的渲染，否则没有触发destroyed无法二次渲染值-->
<template>
  <div>
    <Editor :id="id" v-model="currentValue" :init="init" :disabled="disabled" @onClick="onClick"/>
  </div>
</template>
<script>
import tinymce from 'tinymce/tinymce';
import Editor from '@tinymce/tinymce-vue';
import "tinymce/themes/silver/theme";
import "tinymce/icons/default/icons"//图标
import "tinymce/skins/ui/oxide/skin.css";
import './zh_CN.js'; //从官网下载语言包
import 'tinymce/plugins/image'; //上传图片插件
import 'tinymce/plugins/link'; //超链接
import 'tinymce/plugins/code'; //源码
import 'tinymce/plugins/table'; //插入表格插件
import 'tinymce/plugins/lists'; //列表插件
import 'tinymce/plugins/wordcount';// 字数统计插件
import './utils/wordlimit'// 字数限制插件
//import "tinymce/plugins/media";
import "./utils/media";//视频上传插件，由于自带的存在上传视频后会显示出两个相同视频的bug，修改node_modules\tinymce\plugins\media\plugin.js源码制作
import './emojis.js';
import 'tinymce/plugins/emoticons';
import "tinymce/plugins/contextmenu";
import "tinymce/plugins/colorpicker";//颜色选择器
import "tinymce/plugins/textcolor";//字体颜色
import "tinymce/plugins/preview";//预览
import "tinymce/plugins/advlist";
import "tinymce/plugins/codesample";
import "tinymce/plugins/hr";
import "tinymce/plugins/fullscreen";
import "tinymce/plugins/textpattern";
import "tinymce/plugins/searchreplace";
import "tinymce/plugins/autolink";
import "tinymce/plugins/directionality";
import "tinymce/plugins/visualblocks";
import "tinymce/plugins/visualchars";
import "tinymce/plugins/template";
import "tinymce/plugins/charmap";
import "tinymce/plugins/nonbreaking";
import "tinymce/plugins/insertdatetime";//插入当前时间
import "tinymce/plugins/imagetools";
import "tinymce/plugins/autosave";
import "tinymce/plugins/autoresize";
import "tinymce/plugins/paste";
import "tinymce/plugins/print";
import "tinymce/plugins/quickbars";
import "tinymce/plugins/emoticons";
import "tinymce/plugins/bbcode";
import "tinymce/plugins/tabfocus";
import { getToken } from "@/utils/auth";
let num = 1
export default {
  name: 'TinymceEditor',
  components: {
    Editor,
  },
  props: {
    /**
     * 上传文件关联的业务表
     */
    tableName: {
      type: String,
      default: ''
    },
    /**
     * 绑定值富文本内容
     */
    value: {
      type: String,
      default: ''
    },
    /**
     * 唯一id
     */
    id: {
      type: String,
      default: () => {
        num === 10000 && (num = 1)
        return `tinymce${+new Date()}${num++}`
      }
    },
    /**
     * 初始高度
     */
    height: {
      type: Number,
      default: 500,
    },
    /**
     * 最大输入字符长度
     */
    maxLength: {
      type: Number,
      default: 100000,
    },
    /**
     * 是否禁用
     */
    disabled: {
      type: Boolean,
      default: false,
    },
    /**
     * 需要使用的插件
     */
    plugins: {
      type: [String, Array],
      default: 'lists advlist autolink code codesample directionality fullscreen hr image imagetools insertdatetime link media ' +
          'nonbreaking preview searchreplace table template textpattern visualblocks visualchars wordcount wordlimit emoticons'
    },
    /**
     * 工具栏显示配置
     */
    toolbar: {
      type: [String, Array],
      default: 'fontselect fontsizeselect forecolor backcolor bold italic underline strikethrough | alignleft aligncenter alignright alignjustify outdent indent' +
          ' | h2 h3 table numlist bullist hr | image media link emoticons | blockquote removeformat subscript superscript insertdatetime preview fullscreen'
    }
  },
  data(){
    return {
      currentValue:this.value,
      isChinese:false,
      htmlText:"",
      init: {
        //容器，可使用css选择器
        selector: `#${this.id}`,
        //语言类型
        language: 'zh_CN',
        //编辑器高度
        height: this.height,
        min_height: 100,
        highlight_on_focus: true,
        draggable_modal: true,
        //拼写检查
        browser_spellcheck: true,
        //禁用编辑器底部的状态栏
        //elementpath: false,
        //隐藏编辑器底部的状态栏
        //statusbar: false,
        //允许粘贴图像
        paste_data_images: true,
        //最顶部文字信息
        menubar: false,
        //指定需加载的插件
        plugins: this.plugins,
        //自定义工具栏
        toolbar: this.toolbar,
        //是否禁用“Powered by TinyMCE”
        branding: false,
        //表情
        emoticons_database_url: 'emojis.js',
        //图片标题
        image_caption: true,
        //图片上传处理
        images_upload_handler: (blobInfo, success, failure, progress) => {
          let _this=this
          let xhr, formData;
          xhr = new XMLHttpRequest();
          xhr.withCredentials = false;
          xhr.open('POST', process.env.VUE_APP_BASE_API + "/file/upload");
          xhr.setRequestHeader('Api-Admin-Token', getToken());
          xhr.onerror = function () {
            this.$message.error("上传图片失败")
          };
          xhr.onload = function() {
            const data = JSON.parse(xhr.responseText);
            if (xhr.status != 200) {
              failure('上传图片失败，状态码：' + xhr.status);
              return;
            }
            if(data.code != 200){
              failure(data.msg);
              return;
            }
            let json = JSON.parse(xhr.responseText);
            if (!json.location) {
              json.location = json.data.fileUrl;
              success(json.location);
            }
          };
          formData = new FormData();
          formData.append('file', blobInfo.blob(), blobInfo.filename());
          formData.append('tableName', this.tableName);
          xhr.send(formData);
        },
        //允许实时嵌入媒体
        media_live_embeds: true,
        //启用视频预览图
        //media_poster: true,
        //是否允许用户自定义尺寸
        media_dimensions: true,
        //视频上传处理
        file_picker_types: 'media',
        file_picker_callback: (callback, value, meta) => {
          let _this=this
          // 当点击媒体按钮时，会触发这个回调函数
          if (meta.filetype == 'media') {
            //创建一个隐藏的type=file的文件选择input
            let input = document.createElement('input');
            input.setAttribute('type', 'file');
            input.setAttribute('accept', 'video/*');
            input.onchange = function () {
              //只选取第一个文件。如果要选取全部，后面注意做修改
              let file = this.files[0];
              let xhr, formData;
              xhr = new XMLHttpRequest();
              xhr.open('POST', process.env.VUE_APP_BASE_API + "/file/upload");
              xhr.setRequestHeader('Api-Admin-Token', getToken());
              xhr.onload = function () {
                const data = JSON.parse(xhr.responseText);
                if (xhr.status < 200 || xhr.status >= 300) {
                  callback("上传视频失败，状态码："+ xhr.status);
                  return;
                }
                if(data.code != 200){
                  callback(data.msg);
                }
                let json = JSON.parse(xhr.responseText);
                //接口返回的文件保存地址
                let mediaLocation = json.data.fileUrl;
                callback(mediaLocation, {title: json.data.originalName});
              };
              formData = new FormData();
              formData.append('file', file);
              formData.append('tableName', _this.tableName);
              xhr.send(formData);
            };
            //触发点击
            input.click();
          }
        },
        wordlimit: {
          max: this.maxLength, // 最多可以输入多少字
          spaces: !1, // 是否含空格
          isInput: !1, // 是否在超出后还可以输入
          // 自定义的提示方法, 默认用编辑器自带
          toast: function (message) {
          }
        },
        init_instance_callback: (editor) => {
          const _this = this
          editor.on('wordlimit', function (e) {
            let beyond = 0;
            if (e.wordCount > e.maxCount) {
              beyond = e.wordCount - e.maxCount;
            }
            _this.$message.error('最多只能输入' + e.maxCount + '个字' + (beyond > 0 ? '，已超出' + beyond + '个字，超出部分请删除' : '。'))
          });
        },
        fontsize_formats: '12px 14px 16px 18px 24px 36px 48px 56px 72px',
        font_formats: '微软雅黑=Microsoft YaHei;苹果苹方=PingFang SC;宋体=simsun,serif;' +
          '仿宋体=FangSong;黑体=SimHei;Arial=arial;Arial Black=arial black;Book Antiqua=book antiqua;',
        setup: function(editor) {
          editor.on('init', function(ed) {
            console.log(ed);
            ed.target.editorCommands.execCommand("fontName", false, "微软雅黑");
          });
        }
      },
    }
  },
  watch: {
    value(newValue) {
      this.$nextTick(() => {
        this.currentValue = newValue
      });
    },
    currentValue(newValue) {
      //输入编辑器触发事件
      this.$emit('input', newValue)
    }
  },
  mounted() {
    tinymce.init({})
  },
  destroyed() {
    this.destroyTinymce()
  },
  methods: {
    /**
     * 获取编辑框内容
     * @returns {string|null}
     */
    getContent() {
      return this.currentValue ? this.currentValue : null
    },
    /**
     * 设置编辑框内容
     * @param value
     */
    setContent(value) {
      this.currentValue = value || ''
    },
    /**
     * 点击编辑器触发事件
     */
    onClick() {
      //获取纯文本值，不包含html标签
      let content = tinymce.activeEditor.getContent({ format: 'text' })
      this.$emit('onClick',this.value,content)
    },
    /**
     * 销毁编辑器实例
     */
    destroyTinymce() {
      const editor = tinymce.get(this.id)
      if (editor) {
        editor.destroy()
      }
    }
  }
}
</script>
<style>
/*在el-dialog中tinymce z-index 被太小而被遮挡处理*/
.tox-tinymce-aux{
  z-index:9999 !important;
}
</style>
